package com.df.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.df.common.*;
import com.df.demo.MsgHandlers;
import com.df.msgs.Req_Login;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.Attribute;

import java.net.InetSocketAddress;

public class WebSocketServerHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
        try
        {
            if (frame instanceof TextWebSocketFrame)
            {
                handleMessage(((TextWebSocketFrame) frame).text(), ctx.channel(), ctx);
            }
            else if (frame instanceof PingWebSocketFrame)
            {
                ctx.channel().write(new PongWebSocketFrame(frame.content()));
            }
            else if (frame instanceof BinaryWebSocketFrame)
            {
                ctx.close();

//                ByteBuf in = frame.content();
//                if (frame.isFinalFragment() == false)
//                {
//                    if (tempByteBuf == null)
//                    {
//                        tempByteBuf = ctx.alloc().heapBuffer();
//                    }
//                    tempByteBuf.writeBytes(in);
//                }
//                else
//                {
//                    handleMessage(in, ctx.channel(), ctx);
//                }
            }
            else if (frame instanceof ContinuationWebSocketFrame)
            {
//                tempByteBuf.writeBytes(frame.content());
//                if (frame.isFinalFragment() == true)
//                {
//                    handleMessage(tempByteBuf, ctx.channel(), ctx);
//                    tempByteBuf.clear();
//                }
            }
            else
            {
                System.out.println("channelRead0 error, unsupport webSocketFrame type = "+frame.getClass().getName());
                ctx.close();
            }
        }
        catch (Exception e)
        {
            InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
//            logger.error("channelRead0 error, ip = {}, exception = ", insocket.getAddress().getHostAddress(), e);
            System.out.println("channelRead0 error, ip = "+insocket.getAddress().getHostAddress()+", exception = "+e.getMessage());
        }
    }

    private void handleMessage(String text, Channel channel, ChannelHandlerContext ctx) {
        System.out.println("收到消息："+text);
        try {
            JSONObject jsonObject = JSON.parseObject(text);
            Integer msgId = jsonObject.getInteger("msgId");
            Class msgClass = MsgDefine.getMsgClass(msgId);
            Object o = JSON.parseObject(text, msgClass);
//            IHandler handler = MsgHandlerManger.getInstance().getHandler(msgId);
//            if(handler!=null){
//                handler.handler(channel, (IMsg) o);
//            }else {
//                System.out.println("未知的消息id“："+msgId);
//            }

            if(o instanceof Req_Login){//登录消息在当前线程或其他线程处理
            MsgHandlers.getInstance().dispatch(channel, (IMsg) o);
            }else{//其他消息放到地图线程
                MsgWrapper msgWrapper = new MsgWrapper();
                msgWrapper.channel = channel;
                msgWrapper.msg = (IMsg) o;
                MapThread.getInstance().addMsg(msgWrapper);
            }

//            MsgHandlers.getInstance().dispatch(channel, (IMsg) o);
        }catch (Exception e) {
            e.printStackTrace();
        }


    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("有新连接！");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Attribute<String> attr = ctx.channel().attr(MapThread.uidKey);
        String playerId = attr.get();
        if(playerId != null){
            System.out.println("有玩家断开连接："+playerId);
            MapThread.getInstance().players.remove(playerId);
        }
        super.channelInactive(ctx);
    }
}
